package com.cmsz.collection.service.impl;

import com.cmsz.collection.bean.LogBean;
import com.cmsz.collection.constant.LogCollectionConstant;
import com.cmsz.collection.service.InfoFilter;
import com.cmsz.collection.util.DateUtil;
import net.sf.json.JSONObject;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author panyaoan
 * @date 2019/12/16
 * @description 日志过滤实现
 */
@Service
public class InfoFilterImpl implements InfoFilter {

    private static final Pattern patternTime = Pattern.compile("([2][0]\\d{2})-([0,1]\\d)-([0,1,2,3]\\d) ([0,1,2]\\d):([0,1,2,3,4,5,6]\\d):([0,1,2,3,4,5,6]\\d).\\d{3}");
    private static final Pattern patternTime2 = Pattern.compile("([\\D])([2][0]\\d{2})([0,1]\\d)([0,1,2,3]\\d)([0,1,2]\\d)([0,1,2,3,4,5,6]\\d)([0,1,2,3,4,5,6]\\d)\\d{3}[\\D]");
    private static final Pattern patternSerial = Pattern.compile("[\\D]([\\da-zA-Z]{32})[\\D]");
    private static final Pattern patternSerial2 = Pattern.compile("[\\D]([\\da-zA-Z]{30})[\\D]");

    private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    private static final SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyyMMddHHmmssSSS");

    @Override
    public BulkRequest infoToLog(ConsumerRecord record, BulkRequest bulkRequest) throws ParseException {

        JSONObject value = JSONObject.fromObject(record.value());
        String message = (String) value.get("message");
        JSONObject fields = JSONObject.fromObject(value.get("fields"));
        String hostName = (String) fields.get("hostName");
        String applicationName = (String) fields.get("applicationName");
        //TODO 根据applicationName调用查询缓存接口

        //配置IndexName
        IndexRequest indexRequest = new IndexRequest("test5"+applicationName, "log");
        LogBean logBean = new LogBean();

        String topic = record.topic();
        if(LogCollectionConstant.INFO_TYPE.equals(topic)){
            logBean.setFileType(topic);
            logBean = getInfoLog(message,topic);
        }else{
            logBean.setFileType(topic);
            logBean = getAlarmAndMessageLog(message,topic);
        }

        logBean.setHostIp(hostName);
        logBean.setMessage(message);

        JSONObject source = JSONObject.fromObject(logBean);
        indexRequest.source(source, XContentType.JSON);
        bulkRequest.add(indexRequest);
        return bulkRequest;
    }

    public LogBean getAlarmAndMessageLog(String str,String type) throws ParseException {
        LogBean logBean = new LogBean();

        setLogSerialCode(logBean,str);
        setLogTimeCode(logBean,str,type);

        logBean.setFileType(type);

        return logBean;
    }

    public LogBean getInfoLog(String str,String type) throws ParseException {
        LogBean logBean = new LogBean();
        String logLevel = str.substring(0, 4);

        boolean islogLevel = LogCollectionConstant.INFO_LEVEL.equals(logLevel)
                || LogCollectionConstant.ERRO_LEVEL.equals(logLevel)
                || LogCollectionConstant.WARN_LEVEL.equals(logLevel);

        if(islogLevel){
            setLogSerialCode(logBean,str);
            setLogTimeCode(logBean,str,type);
        }else{
            Long nowTime = DateUtil.getTime2().getTime();
            logBean.setTimestamp(nowTime.toString());
            logBean.setTransId(LogCollectionConstant.SERIAL);
        }
        logBean.setFileType(type);
        return logBean;
    }

    private void setLogSerialCode(LogBean logBean,String str){
        if (str.contains(LogCollectionConstant.SERIAL)){
            str = str.substring(str.indexOf(LogCollectionConstant.SERIAL),str.indexOf(LogCollectionConstant.SERIAL)+38);
            if(str.contains("#")){
                str = str.substring(LogCollectionConstant.SERIAL.length()+1,str.indexOf("#"));
                logBean.setTransId(str);
            }else{
                String[] strC = str.split("[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]");
                logBean.setTransId(strC[1]);
            }
        }else if (str.contains(LogCollectionConstant.PAYTRANS)){
            str = str.substring(str.indexOf(LogCollectionConstant.PAYTRANS),str.indexOf(LogCollectionConstant.PAYTRANS)+42);
            if (str.contains("|")){
                str = str.substring(LogCollectionConstant.PAYTRANS.length(),str.indexOf("|"));
                logBean.setTransId(str);
            }else{
                String[] strC = str.split("[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]");
                logBean.setTransId(strC[1]);
            }
        }else{
            Matcher matcher = patternSerial.matcher(str);
            if(matcher.find()){
                String transId = matcher.group(0);
                transId = transId.substring(1,33);
                logBean.setTransId(transId);
            }else {
                matcher = patternSerial2.matcher(str);
                if(matcher.find()) {
                    String transId = matcher.group(0);
                    transId = transId.substring(1, 31);
                    logBean.setTransId(transId);
                }else{
                    logBean.setTransId("10086");
                }
            }
        }
    }

    private void setLogTimeCode(LogBean logBean,String str,String type) throws ParseException {
        if(LogCollectionConstant.ALARM_TYPE.equals(type)){
            Matcher matcher = patternTime2.matcher(str);
            setLogTime(matcher,logBean,type);
        }else{
            Matcher matcher = patternTime.matcher(str);
            setLogTime(matcher,logBean,type);
        }
    }

    private void setLogTime(Matcher matcher,LogBean logBean,String type) throws ParseException {
        if(matcher.find()){
            Long strTime;
            if(LogCollectionConstant.ALARM_TYPE.equals(type)){
                String str = matcher.group(0);
                str = str.substring(1,18);
                strTime = simpleDateFormat2.parse(str).getTime();
            }else{
                strTime = simpleDateFormat.parse(matcher.group(0)).getTime();
            }
            logBean.setTimestamp(strTime.toString());
        }else {
            Long nowTime = DateUtil.getTime2().getTime();
            logBean.setTimestamp(nowTime.toString());
        }

    }

}
